home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1998 #3 / Amiga Plus CD - 1998 - No. 3.iso / pd / spiele / frotz / source / amiga_stdio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-06  |  11.0 KB  |  570 lines

  1. /*
  2.  * amiga_stdio.c
  3.  *
  4.  * Standard IO interface for the Amiga and DICE C
  5.  *
  6.  * Changes to distributed source are indicated by comments containing
  7.  * the keyword AMIGA.
  8.  *
  9.  */
  10.  
  11. #include <proto/exec.h>
  12. #include <dos/dosextens.h>
  13. #include <stdarg.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <time.h>
  18. #include "frotz.h"
  19.  
  20. #define INFORMATION "\
  21. \n\
  22. FROTZ V2.32 - interpreter for all Infocom games. Complies with standard\n\
  23. 1.0 of Graham Nelson's specification. Written by Stefan Jokisch in 1995-7\n\
  24. Amiga version by David Kinder\n\
  25. \n\
  26. Syntax: frotz [options] story-file\n\
  27. \n\
  28.   -a   watch attribute setting  \t -p   alter piracy opcode\n\
  29.   -A   watch attribute testing  \t -r # right margin\n\
  30.   -c # context lines            \t -s # random number seed value\n\
  31.   -f # foreground colour        \t -S # transscript width\n\
  32.   -h # screen height            \t -t   set Tandy bit\n\
  33.   -i   ignore runtime errors    \t -u # slots for multiple undo\n\
  34.   -l # left margin              \t -w # screen width\n\
  35.   -o   watch object movement    \t -x   expand abbreviations g/x/z\n\
  36.   -O   watch object locating"
  37.  
  38. static int current_style = 0;
  39. static int saved_style = 0;
  40. static int user_tandy_bit = -1;
  41. static int user_random_seed = -1;
  42.  
  43. int getopt (int, char *[], const char *);
  44.  
  45. extern const char *optarg;
  46. extern int optind;
  47.  
  48. char Version[] = "$VER:FrotzStdIO 2.32 (12.10.97)";
  49.  
  50. struct Process *ThisProcess;
  51. struct Window *OldWindowPtr;
  52.  
  53. static int stdio_width = 77;
  54. static int stdio_height = 21;
  55. static int stdio_colour = 1;
  56. static int stdio_x,stdio_y;
  57. static int stdio_break = 1;
  58. static int stdio_time = 0;
  59. static char stdio_save[MAX_FILE_NAME+1];
  60. static time_t start_time;
  61. static int warning = 0;
  62.  
  63. void get_cursor (int *row, int *col);
  64. int brk(void);
  65. void reset_win_ptr(void);
  66.  
  67. void os_beep (int number)
  68. {
  69. }
  70.  
  71. void os_display_char (zchar c)
  72. {
  73.   if (c == ZC_INDENT)
  74.   {
  75.     os_display_char(' ');
  76.     os_display_char(' ');
  77.     os_display_char(' ');
  78.     return;
  79.   }
  80.   if (c == ZC_GAP)
  81.   {
  82.     os_display_char(' ');
  83.     os_display_char(' ');
  84.     return;
  85.   }
  86.  
  87.   if ((c >= ZC_ASCII_MIN && c <= ZC_ASCII_MAX) || (c >= ZC_LATIN1_MIN && c <= ZC_LATIN1_MAX))
  88.   {
  89.     putchar(c);
  90.     stdio_x++;
  91.   }
  92. }
  93.  
  94. void os_display_string (const zchar *s)
  95. {
  96. int c;
  97.  
  98.   while ((c = *s++) != 0)
  99.   {
  100.     if (c == ZC_NEW_FONT || c == ZC_NEW_STYLE)
  101.     {
  102.       int arg = (zchar)*s++;
  103.  
  104.       if (c == ZC_NEW_FONT) os_set_font(arg);
  105.       if (c == ZC_NEW_STYLE) os_set_text_style(arg);
  106.     }
  107.     else os_display_char(c);
  108.   }
  109. }
  110.  
  111. void os_erase_area (int top, int left, int bottom, int right)
  112. {
  113. int row, col, i;
  114.  
  115.   fflush(stdout);
  116.   get_cursor(&row,&col);
  117.   for(i = bottom;i >= top;i--)
  118.   {
  119.     os_set_cursor(i,0);
  120.     printf("\033[K");
  121.   }
  122.   os_set_cursor(row,col);
  123. }
  124.  
  125. void os_fatal (const char *s)
  126. {
  127.   fflush(stdout);
  128.   fputs("\nFatal error: ",stderr);
  129.   fputs(s,stderr);
  130.   fputs("\n",stderr);
  131.  
  132.   exit(1);
  133. }
  134.  
  135. void os_finish_with_sample (void)
  136. {
  137. }
  138.  
  139. int os_font_data (int font, int *height, int *width)
  140. {
  141.   *height = h_font_height;
  142.   *width = h_font_width;
  143.  
  144.   if (font == TEXT_FONT) return 1;
  145.   if (font == GRAPHICS_FONT) return 1;
  146.   if (font == FIXED_WIDTH_FONT)    return 1;
  147.   return 0;
  148. }
  149.  
  150. int os_read_file_name (char *file_name, const char *default_name, int flag)
  151. {
  152. FILE *fp;
  153. int c;
  154. int first = 1;
  155. char *number;
  156. int saved_replay = istream_replay;
  157. int saved_record = ostream_record;
  158. int result = 0;
  159.  
  160.   fflush(stdout);
  161.  
  162.   istream_replay = 0;
  163.   ostream_record = 0;
  164.  
  165.   if (strcmp(stdio_save,"") != 0)
  166.   {
  167.     if ((flag == FILE_SAVE) || (flag == FILE_RESTORE))
  168.     {
  169.       strcpy(file_name,stdio_save);
  170.       if ((number = strchr(file_name,'?')) == 0)
  171.       {
  172.     result = 1;
  173.     goto finished;
  174.       }
  175.  
  176.       print_string("Current saved games:");
  177.       for ( c = '0'; c <= '9'; c++ )
  178.       {
  179.     *number = c;
  180.     if (access(file_name,0) == 0)
  181.     {
  182.       first ? first = 0 : print_char(',');
  183.       print_char(c);
  184.     }
  185.       }
  186.       print_string("\nEnter game number (0-9):");
  187.       flush_buffer();
  188.       do c = os_read_key(0,1); while (c < '0' || c > '9');
  189.       print_string("\n");
  190.       *number = c;
  191.       result = 1;
  192.     }
  193.     goto finished;
  194.   }
  195.  
  196.   print_string("Enter a file name.\n");
  197.   print_string("Default is \"");
  198.   print_string(default_name);
  199.   print_string("\": ");
  200.  
  201.   read_string(MAX_FILE_NAME-4,file_name);
  202.   if (file_name[0] == 0) strcpy(file_name,default_name);
  203.  
  204.   result = 1;
  205.   if (flag == FILE_SAVE || flag == FILE_SAVE_AUX || flag == FILE_RECORD)
  206.   {
  207.     if ((fp = fopen(file_name,"rb")) == NULL) goto finished;
  208.     fclose(fp);
  209.     result = read_yes_or_no("Overwrite existing file");
  210.   }
  211.  
  212. finished:
  213.  
  214.   istream_replay = saved_replay;
  215.   ostream_record = saved_record;
  216.   return result;
  217. }
  218.  
  219. void os_init_screen (void)
  220. {
  221.   atexit(reset_win_ptr);
  222.   ThisProcess = (struct Process *)FindTask(0);
  223.   OldWindowPtr = ThisProcess->pr_WindowPtr;
  224.   ThisProcess->pr_WindowPtr = (void *)~0;
  225.  
  226.   onbreak(brk);
  227.   os_set_cursor(1,1);
  228.   if (stdio_colour >= 8)
  229.     printf("\033[J\033[0;1;3%dm",stdio_colour-8);
  230.   else
  231.     printf("\033[J\033[0;3%dm",stdio_colour);
  232.   time(&start_time);
  233.  
  234.   if (h_version == V3)
  235.   {
  236.     h_config |= CONFIG_SPLITSCREEN;
  237.     if (user_tandy_bit != -1) h_config |= CONFIG_TANDY;
  238.     if (h_flags & OLD_SOUND_FLAG) h_flags &= ~OLD_SOUND_FLAG;
  239.   }
  240.   if (h_version >= V4)
  241.   {
  242.     h_config |= CONFIG_BOLDFACE;
  243.     h_config |= CONFIG_EMPHASIS;
  244.     h_config |= CONFIG_FIXED;
  245.     if (h_flags & SOUND_FLAG) h_flags &= ~SOUND_FLAG;
  246.   }
  247.   if (h_version >= V5)
  248.   {
  249.     if (h_flags & UNDO_FLAG)
  250.     {
  251.       if (option_undo_slots == 0) h_flags &= ~UNDO_FLAG;
  252.     }
  253.     if (h_flags & COLOUR_FLAG) h_flags &= ~COLOUR_FLAG;
  254.   }
  255.   if (h_version == V6)
  256.   {
  257.     h_flags &= ~MENU_FLAG;
  258.   }
  259.  
  260.   h_default_foreground = BLACK_COLOUR;
  261.   h_default_background = WHITE_COLOUR;
  262.   h_interpreter_number = INTERP_AMIGA;
  263.   h_interpreter_version = h_version != V6 ? 'C' : 3;
  264.   h_screen_cols = stdio_width;
  265.   h_screen_rows = stdio_height;
  266.   h_font_width = 1;
  267.   h_font_height = 1;
  268.   h_screen_width = h_screen_cols;
  269.   h_screen_height = h_screen_rows;
  270. }
  271.  
  272. void os_more_prompt (void)
  273. {
  274. int saved_style;
  275. int saved_x,saved_y;
  276. int new_x,new_y;
  277.  
  278.   fflush(stdout);
  279.  
  280.   saved_style = current_style;
  281.   os_set_text_style(0);
  282.  
  283.   get_cursor(&saved_y,&saved_x);
  284.   os_display_string("[MORE]");
  285.   os_read_key(0,1);
  286.  
  287.   get_cursor(&new_y,&new_x);
  288.   os_erase_area(new_y,saved_x,new_y+h_font_height,new_x);
  289.   os_set_cursor(saved_y,saved_x);
  290.   os_set_text_style(saved_style);
  291. }
  292.  
  293. void os_prepare_sample (int number)
  294. {
  295. }
  296.  
  297. void os_process_arguments (int argc, char *argv[])
  298. {
  299. int num;
  300. int c;
  301.  
  302.   do
  303.   {
  304.     optarg = 0;
  305.     c = getopt(argc,argv,"aAc:Cf:h:il:oOpr:s:S:tT:u:V:w:x");
  306.  
  307.     if (optarg != 0) num = atoi(optarg);
  308.  
  309.     switch (c)
  310.     {
  311.       case 'a': option_attribute_assignment = 1;
  312.         break;
  313.       case 'A': option_attribute_testing = 1;
  314.         break;
  315.       case 'c': option_context_lines = num;
  316.         break;
  317.       case 'C': stdio_break = 0;
  318.         break;
  319.       case 'f': stdio_colour = num;
  320.         break;
  321.       case 'h': stdio_height = num;
  322.         break;
  323.       case 'i': option_ignore_errors = 1;
  324.         break;
  325.       case 'l': option_left_margin = num;
  326.         break;
  327.       case 'o': option_object_movement = 1;
  328.         break;
  329.       case 'O': option_object_locating = 1;
  330.         break;
  331.       case 'p': option_piracy = 1;
  332.         break;
  333.       case 'r': option_right_margin = num;
  334.         break;
  335.       case 's': user_random_seed = num;
  336.         break;
  337.       case 'S': option_script_cols = num;
  338.         break;
  339.       case 't': user_tandy_bit = 1;
  340.         break;
  341.       case 'T': stdio_time = num;
  342.         break;
  343.       case 'u': option_undo_slots = num;
  344.         break;
  345.       case 'V': strcpy(stdio_save,optarg);
  346.         break;
  347.       case 'w': stdio_width = num;
  348.         break;
  349.       case 'x': option_expand_abbreviations = 1;
  350.         break;
  351.     }
  352.   }
  353.   while (c != EOF);
  354.  
  355.   if (optind != argc-1)
  356.   {
  357.     puts(INFORMATION);
  358.     exit(1);
  359.   }
  360.  
  361.   story_name = argv[optind];
  362. }
  363.  
  364. zchar os_read_line (int max, zchar *buf, int timeout, int width, int continued)
  365. {
  366. int row, col;
  367. zchar *trail;
  368.  
  369.   fflush(stdout);
  370.   get_cursor(&row,&col);
  371.   fgets(buf,max,stdin);
  372.   if (trail = strrchr(buf,'\n')) *trail = '\0';
  373.   os_set_cursor(row,col+strlen(buf));
  374.  
  375. time_t current_time;
  376.  
  377.   if (stdio_time > 0)
  378.   {
  379.     time(¤t_time);
  380.     if ((current_time-start_time)/60 >= stdio_time)
  381.     {
  382.       screen_new_line();
  383.       os_display_string("You are out of time for this session.");
  384.       screen_new_line();
  385.       os_display_string("Exiting...");
  386.       screen_new_line();
  387.       exit(0);
  388.     }
  389.     if (((current_time-start_time)/60 >= stdio_time-5) && (warning == 0))
  390.     {
  391.       screen_new_line();
  392.       os_display_string("You have 5 minutes left.n");
  393.       screen_new_line();
  394.       warning = 1;
  395.     }
  396.     if (((current_time-start_time)/60 >= stdio_time-1) && (warning == 1))
  397.     {
  398.       screen_new_line();
  399.       os_display_string("You have 1 minute left.");
  400.       screen_new_line();
  401.       warning = 2;
  402.     }
  403.   }
  404.  
  405.   return ZC_RETURN;
  406. }
  407.  
  408. zchar os_read_key (int timeout, bool cursor)
  409. {
  410. int row, col, c;
  411.  
  412.   fflush(stdout);
  413.   get_cursor(&row,&col);
  414.   c = getchar();
  415.   os_set_cursor(row,col);
  416.   return c;
  417. }
  418.  
  419. void os_reset_screen (void)
  420. {
  421.   fflush(stdout);
  422.   printf("\033[0m");
  423. }
  424.  
  425. void os_scroll_area (int top, int left, int bottom, int right, int units)
  426. {
  427.   fflush(stdout);
  428.   while (units > 0)
  429.   {
  430.     os_set_cursor(top,0);
  431.     printf("\033[M");
  432.     units--;
  433.   }
  434.   os_set_cursor(h_screen_rows,0);
  435. }
  436.  
  437. void os_set_colour (int new_foreground, int new_background)
  438. {
  439. }
  440.  
  441. void os_set_cursor (int row, int col)
  442. {
  443.   fflush(stdout);
  444.   printf("\033[%d;%dH",row,col);
  445.   stdio_x = col;
  446.   stdio_y = row;
  447. }
  448.  
  449. void os_set_font (int new_font)
  450. {
  451. }
  452.  
  453. void os_set_text_style (int new_style)
  454. {
  455.   fflush(stdout);
  456.   current_style = new_style;
  457.  
  458.   if (stdio_colour >= 8)
  459.     printf("\033[0;1;3%dm",stdio_colour-8);
  460.   else
  461.     printf("\033[0;3%dm",stdio_colour);
  462.  
  463.   if (new_style & REVERSE_STYLE)
  464.   {
  465.     printf("\033[7m");
  466.   }
  467.  
  468.   if (new_style & BOLDFACE_STYLE)
  469.   {
  470.     printf("\033[1m");
  471.   }
  472.  
  473.   if (new_style & EMPHASIS_STYLE)
  474.   {
  475.     printf("\033[4m");
  476.   }
  477. }
  478.  
  479. void os_start_sample (int number, int volume, int repeats)
  480. {
  481. }
  482.  
  483. void os_stop_sample (void)
  484. {
  485. }
  486.  
  487. int os_string_width (const zchar *s)
  488. {
  489. int length,i,c;
  490.  
  491.   length = 0;
  492.  
  493.   for (i = 0; s[i] != 0; i++)
  494.   {
  495.     c = s[i];
  496.     if ((c == ZC_NEW_STYLE) || (c == ZC_NEW_FONT)) i++;
  497.     if (c == ZC_INDENT) length += 3;
  498.     if (c == ZC_GAP) length += 2;
  499.     if ((c >= ZC_ASCII_MIN && c <= ZC_ASCII_MAX) || (c >= ZC_LATIN1_MIN && c <= ZC_LATIN1_MAX))
  500.       length++;
  501.   }
  502.   return length;
  503. }
  504.  
  505. int os_char_width (zchar c)
  506. {
  507. zchar s[2];
  508.  
  509.   s[0] = c;
  510.   s[1] = 0;
  511.   return os_string_width(s);
  512. }
  513.  
  514. int os_peek_colour (void)
  515. {
  516.   return WHITE_COLOUR;
  517. }
  518.  
  519. int os_picture_data (int picture, int *height, int *width)
  520. {
  521.   *height = 0;
  522.   *width = 0;
  523.   return 0;
  524. }
  525.  
  526. void os_draw_picture (int picture, int y, int x)
  527. {
  528. }
  529.  
  530. int os_random_seed (void)
  531. {
  532.   if (user_random_seed == -1) return clock()&32767;
  533.   return user_random_seed;
  534. }
  535.  
  536. void os_restart_game (int stage)
  537. {
  538. }
  539.  
  540. void get_cursor (int *row, int *col)
  541. {
  542.   fflush(stdout);
  543.   *row = stdio_y;
  544.   *col = stdio_x;
  545. }
  546.  
  547. int brk(void)
  548. {
  549.   if (stdio_break)
  550.   {
  551.     fflush(stdout);
  552.     printf("\033[0m\n***Break\n");
  553.     exit(0);
  554.   }
  555.   return 0;
  556. }
  557.  
  558. void reset_win_ptr(void)
  559. {
  560.   if (ThisProcess) ThisProcess->pr_WindowPtr = OldWindowPtr;
  561. }
  562.  
  563. void CheckReset(void)
  564. {
  565. }
  566.  
  567. void Justifiable(void)
  568. {
  569. }
  570.